package wili.sql;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

/**
 * @author weila 2022年7月23日
 */
public abstract class SqlCont0 {
	Supplier<Connection> conSup;

	private Connection conn;

	public String catalog, schema;

	Map<String, Tab> tableMap = new HashMap<>();

	final String dbType, name;

	public String toString() {
		return name;
	}

	public Connection getConn() {
		Connection ret = conSup.get();
		try {
			this.catalog = ret.getCatalog();
			this.schema = ret.getSchema();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return ret;
	}

	public void close() {
		try {
			if (conn != null && !conn.isClosed())
				conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public abstract DatabaseMetaData getDatabaseMetaData(String nam);

	public abstract Map<String, Tab> getTables(String nameReg);

	public abstract Tab getTable(String nam);

	DatabaseMetaData meta;

	public SqlCont0(String type, String name) {
		this.dbType = type;
		this.name = name;
		this.conSup = new Supplier<Connection>() {
			Connection ret;

			@Override
			public Connection get() {
				try {
					switch (dbType) {
					case "mysql":
						if (ret == null || ret.isClosed())
							ret = Conn9a.mysql(name);
						return ret;
					case "hana":
						if (ret == null || ret.isClosed())
							ret = Conn9a.hanaDB();
						return ret;
					default:
						return null;
					}
				} catch (SQLException e) {
					e.printStackTrace();
					return null;
				}
			}
		};
	}

	public ResultSet query(String sql) {
		try {
			Connection conn = this.getConn();
			return conn.createStatement().executeQuery(sql);
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	static void log(Object msg) {
		System.out.println(msg);
	}

	/**
	 * @param regEap
	 * @return {tableName, colName}
	 */
	public String[] findCol(String regEap) {
		Connection conn = getConn();
		DatabaseMetaData meta;
		try {
			meta = conn.getMetaData();
			String schemaPat = conn.getSchema();
			ResultSet res = meta.getTables(null, schemaPat, "*", null);
			List<String> list = new ArrayList<String>();
			while (res.next()) {
				String tableName = res.getString("TABLE_NAME");
				String schem = res.getString("TABLE_SCHEM");
				String cat = res.getString("TABLE_CAT");
			}
			return null;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	DatabaseMetaData getDatabaseMetaData() {
		try {
			return meta = getConn().getMetaData();
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	public Map<String, Tab> findTableMap(String nameReg) {
		Connection conn = this.getConn();
		List<String> names = null;
		if (dbType.equals("hana")) {
			names = Coms.getTables_b1();
		} else {
			names = Coms.findTableNames("", nameReg, conn);
		}
		Map<String, Tab> map = new HashMap<>(names.size());
		int times = 0;
		for (String name : names) {
			//if (++times > 20) break;
			Tab ta = tableMap.get(name);
			if (ta == null) {
				try {
					tableMap.put(name, ta = new Tab(name, this));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			map.put(name, ta);
		}
		return map;
	}

	public List<String> findTableNames(String nameReg) {
		Connection conn = this.getConn();
		List<String> ret = Coms.findTableNames("", nameReg, conn);
		return ret;
	}
}
